Repository navigation
feat(cel): expose the executed file as event.file - #1065
Conversation
trace_exec v0.57 emits file, d_path(bprm->file): the file the kernel executed. For a shebang script it is the script, while exepath is the interpreter and argv[0] is the interpreter as written in the shebang, so no existing CEL field gives rules the script path. Register it as event.file with presence tracking, so has(event.file) reports whether the gadget emits it. Rules use it with an exepath fallback and an agent version gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Register and validate event.file pkg/utils/cel.go, pkg/utils/struct_event.go, pkg/rulemanager/cel/cel_file_test.go, docs/features/exec-file-cel-field.md |
CEL reads the exec file path, and StructEvent reports the field present when its value is non-empty. Tests and documentation cover shebang events, missing fields, fallback expressions, and agent version requirements. |
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Feature
Possibly related issues
- Upgrade Inspektor Gadget to v0.57.0 via kubescape fork and preserve exec/path semantics #1050: This PR documents the executable path and script behavior, but does not implement the issue’s full upgrade or consumer audit.
Possibly related PRs
- kubescape/node-agent#1062: This PR exposes the
filevalue added to the exec datasource as the CEL fieldevent.file.
Suggested reviewers: slashben
Merge Risk: 
Minimal · up to e38bf
-
No actionable merge-blocking issue is identified for event.file. The change appears ready to merge subject to normal checks.
Pre-merge checks: 
5
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 3 files. (1 skipped: 1 unsupported.)
-
Finishing Touches
-
Generate docstrings
-
- Commit to this branch
- Create a new PR
Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the change exposing the executed file path as event.file in CEL rules.
No open issues 🎉
What changed in this PR
Exposes the executed file path as event.file in CEL rules, allowing rules to distinguish shebang scripts from their interpreters following the Inspektor Gadget v0.57 upgrade.
Changes:
- Registers
event.filewith presence detection for datasource and struct-backed events. - Adds tests for shebang paths, missing fields, and fallback behavior.
- Documents field semantics, fallback expressions, and agent-version gating.
| File | Description |
|---|---|
pkg/utils/struct_event.go |
Reports file as present when non-empty. |
pkg/utils/cel.go |
Registers the CEL string field and its presence check. |
pkg/rulemanager/cel/cel_file_test.go |
Tests path access, presence detection, and fallbacks. |
docs/features/exec-file-cel-field.md |
Explains field usage and version requirements. |
Review effort: Balanced
Performance Benchmark ResultsNode-Agent Resource Usage
Dedup EffectivenessNo data available. |
Since Inspektor Gadget v0.57, event.args is the real argv, and argv[0] is chosen by the caller: for a shebang script it's the interpreter, and exec -a sets it to anything. So R1000 missed shebang scripts in /dev/shm and fired on a spoofed argv[0]. The third leg now checks event.file, the file the kernel executed (kubescape/node-agent#1065). The message and uniqueId report event.file, falling back to exepath when it's empty. event.file only exists from node-agent v0.3.307 and private-node-agent v0.0.598, and older agents would fail to compile the rule. It's gated with agentVersionRequirement ">=0.0.598, <0.1.0 || >=0.3.307": one constraint covering both version lines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Docs-exempt: rule docs are in pkg/rules/r1000-exec-from-malicious-source/README.md, updated here Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
Since Inspektor Gadget v0.57, event.args is the real argv, and argv[0] is chosen by the caller: for a shebang script it's the interpreter, and exec -a sets it to anything. So R1000 missed shebang scripts in /dev/shm and fired on a spoofed argv[0]. The third leg now checks event.file, the file the kernel executed (kubescape/node-agent#1065). The message and uniqueId report event.file, falling back to exepath when it's empty. event.file only exists from node-agent v0.3.307, and older agents would fail to compile the rule, so it's gated with agentVersionRequirement ">=0.3.307". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Docs-exempt: rule docs are in pkg/rules/r1000-exec-from-malicious-source/README.md, updated here Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
…54) Since Inspektor Gadget v0.57, event.args is the real argv, and argv[0] is chosen by the caller: for a shebang script it's the interpreter, and exec -a sets it to anything. So R1000 missed shebang scripts in /dev/shm and fired on a spoofed argv[0]. The third leg now checks event.file, the file the kernel executed (kubescape/node-agent#1065). The message and uniqueId report event.file, falling back to exepath when it's empty. event.file only exists from node-agent v0.3.307, and older agents would fail to compile the rule, so it's gated with agentVersionRequirement ">=0.3.307". Docs-exempt: rule docs are in pkg/rules/r1000-exec-from-malicious-source/README.md, updated here Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
Summary
Expose the file the kernel executed as the CEL field
event.file. With Inspektor Gadget v0.57 (#1062), rules have no field that holds a shebang script's path:exepathis the interpreter and argv[0] is the interpreter as written in the shebang.trace_execalready emitsfile(d_path(bprm->file)), and #1062 uses it for alert paths; this makes it available to rules.Overview
event.fileevent.exepathevent.args[0]/bin/ls/usr/bin/ls/usr/bin/lsls/run/x.pid(#!/bin/sh)/run/x.pid/usr/bin/dash/bin/shpkg/utils/cel.go: a newfilestring field withIsSet: presenceOf("file"), sohas(event.file)reports whether the gadget emits it, as forttyMajor.pkg/utils/struct_event.go:FieldPresent("file")is true whenFileis non-empty (ptrace and test events).docs/features/exec-file-cel-field.md: the field, how it differs fromexepath, the(event.file != "" ? event.file : event.exepath)fallback, and the version gate.First user: armosec R1161 (execution of runtime-state files such as
/run/*.pid). Its shebang legs matched argv[0], which is now the interpreter. The team agreed to move it toevent.file, gated withagentVersionRequirementat the first release that includes this. Older agents don't register the field, so an ungated rule would fail to compile there; the rules watcher skips gated rules before compiling them.How to Test
go test ./pkg/rulemanager/cel/ ./pkg/utils/: pass.TestCELExecFilecovers:StructEvent:fileis the script whileexepathis the interpreter;file(has()is false, and the fallback picksexepath);filefield.go vetis clean.Related issues/PRs:
file)🤖 Generated with Claude Code
AI-skills: oh-my-claudecode:plan,oh-my-claudecode:ralph,notify,armosec-shared-rules:open_pr | cmds: /oh-my-claudecode:deep-interview,/gh-review
Summary by CodeRabbit
event.fileto identify the file associated with an exec event. The field is available when provided by the event source; otherwise, rules can fall back toevent.exepath. Rules using this field are skipped on agents that do not meet the required version.event.filediffers fromevent.exepathandevent.args[0], when it is present, and how to handle events where it is empty.